home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 025a / gsdb25.zip / GS_SORT.PAS < prev    next >
Pascal/Delphi Source File  |  1991-08-01  |  5KB  |  194 lines

  1. unit GS_Sort;
  2.  
  3. interface
  4.  
  5. type
  6.    GS_Sort_Objt = object
  7.        Ascending   : boolean;
  8.        Gt_Sign,
  9.        Lt_Sign     : integer;
  10.        constructor InitSort(ascnd : boolean);
  11.        procedure   SortDir(ascnd : boolean);
  12.        procedure   Sort(var tabl; clth : word; icnt : longint);
  13.        function    Search(key : string; var tabl; clth : word;
  14.                                 icnt : longint) : longint;
  15.        function    Compare(var s1, s2) : integer; virtual;
  16.     end;
  17.  
  18. function GS_Sort_Compare(var s1,s2) : integer;
  19. procedure GS_Sort_Swap(var s1,s2; len : word);
  20.  
  21. implementation
  22.  
  23. type
  24.    buf_type         = array[0..0] of byte;
  25.  
  26. var
  27.    buffer           : ^buf_type;
  28.    reclen           : word;             { record length }
  29.  
  30. function GS_Sort_Compare(var s1,s2) : integer;
  31. var
  32.    st1 : string absolute s1;
  33.    st2 : string absolute s2;
  34.    flg : integer;
  35.    eql : boolean;
  36. begin
  37.    eql := st1 = st2;
  38.    Inline(              {Get flag register in flg}
  39.      $9C/                   {  PUSHF           ;Push flag register}
  40.      $59/                   {  POP     CX      ;Get flag register in CX}
  41.      $89/$4E/<flg);         {  MOV     <flg,CX ;Store CX in flg}
  42.    if eql then GS_Sort_Compare := 0
  43.       else if (flg and $0080) = 0 then
  44.          GS_Sort_Compare := 1             {s1 > s2 if sign flag 0}
  45.             else GS_Sort_Compare := -1;   {s1 < s2 if sign flag 1}
  46. end;
  47.  
  48. procedure GS_Sort_Swap(var s1,s2; len : word);
  49. begin
  50.    inline(
  51.       $1E/          { push ds           ; save DS reg }
  52.       $8B/$8E/len/  { mov cx,[bp+4]     ; CX = len }
  53.       $C5/$B6/s1/   { lds si,[bp+10]    ; DS:SI = var s1 }
  54.       $C4/$BE/s2/   { les di,[bp+6]     ; ES:DI = var s2 }
  55.       $FC/          { cld               ; set forward direction }
  56.       $8A/$04/      { mov al,[SI]       ; get a }
  57.       $8A/$25/      { mov ah,[DI]       ; get b }
  58.       $88/$24/      { mov [SI],ah       ; store a }
  59.       $AA/          { stosb             ; store b }
  60.       $46/          { inc si            ; increment }
  61.       $E2/$F6/      { loop ...          ; continue }
  62.       $1F           { pop ds            ; restore DS reg }
  63.    );
  64. end;
  65.  
  66. constructor GS_Sort_Objt.InitSort(ascnd : boolean);
  67. begin
  68.    Ascending := ascnd;
  69.    if ascnd then
  70.    begin
  71.       Gt_Sign := 1;
  72.       Lt_Sign := -1;
  73.    end
  74.    else
  75.    begin
  76.       Gt_Sign := -1;
  77.       Lt_Sign := 1;
  78.    end;
  79. end;
  80.  
  81. procedure GS_Sort_Objt.SortDir(ascnd : boolean);
  82. begin
  83.    Ascending := ascnd;
  84.    if ascnd then
  85.    begin
  86.       Gt_Sign := 1;
  87.       Lt_Sign := -1;
  88.    end
  89.    else
  90.    begin
  91.       Gt_Sign := -1;
  92.       Lt_Sign := 1;
  93.    end;
  94. end;
  95.  
  96. function GS_Sort_Objt.Compare(var s1,s2) : integer;
  97. var
  98.    st1 : string absolute s1;
  99.    st2 : string absolute s2;
  100.    flg : integer;
  101.    eql : boolean;
  102. begin
  103.    eql := st1 = st2;
  104.    Inline(              {Get flag register in flg}
  105.      $9C/                   {  PUSHF           ;Push flag register}
  106.      $59/                   {  POP     CX      ;Get flag register in CX}
  107.      $89/$4E/<flg);         {  MOV     <flg,CX ;Store CX in flg}
  108.    if eql then Compare := 0
  109.       else if (flg and $0080) = 0 then
  110.          Compare := Gt_Sign            {s1 > s2 if sign flag 0}
  111.             else Compare := Lt_Sign;   {s1 < s2 if sign flag 1}
  112. end;
  113.  
  114. {----------------------------------------------------------------------}
  115.  
  116. procedure GS_Sort_Objt.Sort(var tabl; clth : word; icnt : longint);
  117.  
  118.  
  119. { QuickSort algorithm }
  120.  
  121.    procedure qsort(l,r: integer);
  122.    var
  123.       i,j,x             : integer;
  124.       midpoint          : ^buf_type;       { midpoint value }
  125.  
  126.    begin
  127.       i := l;
  128.       j := r;
  129.       x := (l + r) div 2;
  130.       getmem(midpoint,reclen);                { allocate midpoint buffer }
  131.       move(buffer^[x*reclen],midpoint^,reclen);  { get midpoint value }
  132.       repeat
  133.          while Compare(buffer^[i*reclen],midpoint^) < 0 do inc(i);
  134.          while Compare(midpoint^,buffer^[j*reclen]) < 0 do dec(j);
  135.          if i <= j then begin
  136.             GS_Sort_Swap(buffer^[i*reclen],buffer^[j*reclen],reclen);
  137.             inc(i);
  138.             dec(j);
  139.          end;
  140.       until i > j;
  141.       freemem(midpoint,reclen);               { deallocate midpoint buffer }
  142.       if l < j then qsort(l,j);
  143.       if i < r then qsort(i,r);
  144.    end;
  145.  
  146. begin
  147.    buffer := @tabl;
  148.    reclen := clth;
  149.    qsort(0,pred(icnt));
  150. end;
  151.  
  152.  
  153. function  GS_Sort_Objt.Search(key : string; var tabl; clth : word;
  154.                                     icnt : longint) : longint;
  155. var
  156.    l,u,i,j          : integer;
  157.    done             : boolean;
  158.  
  159. begin
  160.    buffer := @tabl;
  161.    l := 0;
  162.    u := icnt;
  163.    done := false;
  164.    while not done do
  165.    begin
  166.       i := (l+u) div 2;                 { compute midpoint of range }
  167.       j := Compare(buffer^[i * clth],key);
  168.       if j=0 then
  169.       begin
  170.          Search := i;
  171.          done := true;
  172.       end else if j<0 then
  173.       begin
  174.          if l=i then
  175.          begin
  176.             Search := -1;
  177.             done := true;
  178.          end else
  179.             l := i;
  180.       end else
  181.       begin
  182.          if u=i then
  183.          begin
  184.             Search := -1;
  185.             done := true;
  186.          end else
  187.             u := i;
  188.       end;
  189.    end;
  190. end;
  191.  
  192.  
  193. end.
  194.